#include "GameObject.h"
#include "CCLuaEngine.h"
//#include <>
/*
"{\"name\":\"objectname\""\
","
"compants":[{"name":"compantname", "normal":"a.png"}, {}]}"
*/


GameObject* GameObject::create(const char* name){
  GameObject * go = new GameObject(name);
  //go->init(plistname);
  go->autorelease();
  GameObjectManager::sharedGameObjectManager()->addGameObject(go);  
  return go;
}

set<string> GameObject::parserPlist(const char* plistname){
  set<string> spriteNames;
  const char *path = CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(plistname);
  CCDictionary *dict = CCDictionary::createWithContentsOfFile(path);
  CCDictionary *frames = (CCDictionary*)dict->objectForKey("frames");
  CCArray *keys = frames->allKeys();
  for(int i=0; i<keys->count(); i++){
    const char * key = ((CCString*)keys->objectAtIndex(i))->getCString();
    CCLog("key %s", key);
    spriteNames.insert(key);
  }
  return spriteNames;
}

void GameObject::init(const char* plistname){
  /*CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(plistname);
  set<string> spriteNames = parserPlist(plistname); 
  set<string>::iterator it = spriteNames.begin();
  for(; it!=spriteNames.end(); ++it){
    CCLog("key %s", (*it).c_str());
  }*/
}

void GameObject::addCompant(const char* compantname, const char* plistname, float scale,  const char* pngname){
  CCLog("GameObject::addCompant --> %s %s %f", compantname, plistname, scale);
  CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(plistname);
  CCSprite *sp = NULL;
  if (pngname && strlen(pngname)>0) {
    sp = CCSprite::createWithSpriteFrameName(pngname);
  }else{
    set<string> spriteNames = parserPlist(plistname);
    if(spriteNames.empty()){
      return;
    }
    CCLog("GameObject::addCompant --> %s", spriteNames.begin()->c_str());
    sp = CCSprite::createWithSpriteFrameName(spriteNames.begin()->c_str());
  }
  sp->setScale(scale); 
  compants_[string(compantname)] = sp;
  CCLog("GameObject::addCompant --> %p", sp);
  this->addChild(sp);
}

void GameObject::addAction(const char* actionname, const char* plistname){
  CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(plistname);
  set<string> spriteNames = parserPlist(plistname);
  if(spriteNames.empty()){
    return;
  }

  CCArray* arr = CCArray::create();  
  set<string>::iterator it = spriteNames.begin();
  for(; it!=spriteNames.end(); ++it){
    string name = (*it).c_str();
    CCLog("key %s", name.c_str());
    CCSpriteFrame *sf = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(name.c_str());
    arr->addObject(sf); 
  }
  CCAnimation *animation = CCAnimation::createWithSpriteFrames(arr, 0.1);
  CCAnimate * ac = CCAnimate::create(animation);
  actions_[string(actionname)] = ac;
  ac->retain();
}

void GameObject::playAction(const char* compantname, const char* actionname, const char* callback){
  CCSprite *sp = compants_[compantname];
  
  map<string, CCAction*>::iterator ait = actions_.find(actionname);
  if(ait==actions_.end()){
    return;
  }
  CCFiniteTimeAction *ac = (CCFiniteTimeAction*)ait->second;
  
  if(callback && strlen(callback)>0){
    pair<set<string>::const_iterator,bool> p = callbacks_.insert(callback);
    CCCallFuncND * func = CCCallFuncND::create(this, callfuncND_selector(GameObject::onAction), (void*)(p.first->c_str()));
    CCFiniteTimeAction *sa = CCSequence::create(ac, func, NULL);
    sp->runAction(sa);
  }else{
    sp->runAction(ac);
  }
}

void GameObject::playActionEx(const char* compantname, CCAction* action, const char* callback){
  CCSprite *sp = compants_[compantname];
  if(callback && strlen(callback)>0){
    pair<set<string>::const_iterator,bool> p = callbacks_.insert(callback);
    CCCallFuncND * func = CCCallFuncND::create(this, callfuncND_selector(GameObject::onAction), (void*)(p.first->c_str()));
    CCFiniteTimeAction *sa = CCSequence::create((CCFiniteTimeAction*)action, func, NULL);
    sp->runAction(sa);
  }else{
    sp->runAction(action);
  } 
}

void GameObject::onAction(CCNode* node, void* data){
  string tmp = (char*)data;
  string name = tmp;
  string flag;
  int pos = tmp.find(":");
  if(pos>0){
    name=tmp.substr(0, pos);
    flag=tmp.substr(pos+1);
  }
  CCLog("onAction --> %s %s", name.c_str(), flag.c_str());
  callbacks_.erase((char*)data);
  CCLuaEngine* pEngine = CCLuaEngine::defaultEngine();
  pEngine->executeGameObjectActionCallback(this, name.c_str(), flag.c_str());
}

CCSprite* GameObject::getCompant(const char* compantname){
  return compants_[compantname];
}

void GameObject::resetCompant(const char* compantname){
  
}




GameObjectManager* GameObjectManager::pSharedGameObjectManager = NULL;

GameObjectManager* GameObjectManager::sharedGameObjectManager()
{
    if (! pSharedGameObjectManager)
    {
        pSharedGameObjectManager= new GameObjectManager();
    }

    return pSharedGameObjectManager;
}

GameObject* GameObjectManager::getGameObject(const char* name){
  map<string, GameObject*>::iterator it = gos_.find(name);
  if(it!=gos_.end()){
    return it->second;
  }
  return NULL;
}

void GameObjectManager::removeGameObject(GameObject* go){
  string name = go->getName();
  gos_.erase(name);
}

bool GameObjectManager::addGameObject(GameObject* go){
  string name = go->getName();
  map<string, GameObject*>::iterator it = gos_.find(name);
  if(it!=gos_.end()){
    return false;
  }
  gos_[name] = go;
}

